package com.zcp.jiesuodemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/4/6.
 */

public class LockDemo extends View {

    //选中点的数量
    private Paint mpaint = new Paint();
    //九宫格
    Point[][] points = new Point[3][3];
    public boolean isInit, isSelect, isFinished, movingNoPoint;
    public float width, height, bitmapR;

    private onPatterChangeListener listener;

    //矩阵(线的缩放)
    private Matrix matrix = new Matrix();
    private static final int POINT_SIZE = 5;
    //鼠标移动时的x,y
    public float movingX, movingY;
    private Bitmap pointNormal, pointError, pointPressed, line_pressed, line_error;

    //点(用来存放按下点击的圆形)
    List<Point> pointList = new ArrayList<>();

    public LockDemo(Context context) {
        super(context);
    }

    public LockDemo(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public LockDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //初始化九宫格
        if (!isInit) {
            initPoints();
        }

        //绘制(将点绘制到画布上)
        points2Cavas(canvas);

        //画线
        if (pointList.size() > 0) {
            Point a = pointList.get(0);

            //绘制九宫格里的坐标点
            for (int i = 0; i < pointList.size(); i++) {
                Point b = pointList.get(i);
                lineCanvas(canvas, a, b);
                a = b;
            }

            //绘制鼠标坐标点
            if (movingNoPoint) {
                lineCanvas(canvas, a, new Point(movingX, movingY));
            }
        }
    }


    //画线(线的缩放,)
    public void lineCanvas(Canvas canvas, Point a, Point b) {
        //线的长度
        float lineLength = (float) Point.distance(a, b);
        float degress = getDegress(a, b);
        canvas.rotate(degress, a.x, a.y);
        if (a.state == Point.STATE_PRESSED) {

            matrix.setScale(lineLength / line_pressed.getWidth(), 1);
            matrix.postTranslate(a.x - line_pressed.getWidth() / 2, a.y - line_pressed.getHeight() / 2);
            //画线
            canvas.drawBitmap(line_pressed, matrix, mpaint);
        } else {
            matrix.setScale(lineLength / line_error.getWidth(), 1);
            matrix.postTranslate(a.x - line_error.getWidth() / 2, a.y - line_error.getHeight() / 2);
            canvas.drawBitmap(line_error, matrix, mpaint);
        }
        canvas.rotate(-degress, a.x, a.y);
    }

    private float getDegress(Point a, Point b) {
        float ax = a.x;
        float ay = a.y;
        float bx = b.x;
        float by = b.y;
        float degress = 0;
        if (bx == ax)//y轴相等,90/270
        {
            if (by > ay)//y轴的下边  90
            {
                degress = 90;
            } else if (by < ay)//y轴的上边  270
            {
                degress = 270;
            } else if (by == ay)//y轴相等 0/180
            {
                if (bx > ax)//y州的下边 90
                {
                    degress = 0;
                } else if (bx < ax)//y轴的上边 270
                {
                    degress = 180;
                }
            }

        }
        return (float) Math.toDegrees(Math.atan2(b.y - a.y, b.x - a.x));
    }

    //初始化点
    private void initPoints() {

        /*
        * 1.获取布局的宽和高
        */
        width = getWidth();
        height = getHeight();

        /*
        * 2.偏移量
        */
        //横屏和竖屏绘制的点不一样
        float offsetsX = 0, offesetsY = 0;
        //横屏
        if (width > height) {
            //横屏的时候是x轴进行了偏移,y轴最短,
            offsetsX = (width - height) / 2;
            width = height;

        }
        //竖屏
        else {
            //九宫格的宽和高以屏幕宽和高中最短的一个为基准
            offesetsY = (height - width) / 2;
            height = width;
        }


        /*
        * 3.图片资源
        */
        pointNormal = BitmapFactory.decodeResource(getResources(), R.drawable.btn_circle_normal);
        pointPressed = BitmapFactory.decodeResource(getResources(), R.drawable.btn_circle_pressed);
        pointError = BitmapFactory.decodeResource(getResources(), R.drawable.btn_circle_selected);
        line_pressed = BitmapFactory.decodeResource(getResources(), R.drawable.ddd);
        line_error = BitmapFactory.decodeResource(getResources(), R.drawable.qqq);

        /*
        * 4.点的坐标
        */
        points[0][0] = new Point(offsetsX + width / 4, offesetsY + width / 4);
        points[0][1] = new Point(offsetsX + width / 2, offesetsY + width / 4);
        points[0][2] = new Point(offsetsX + (width - width / 4), offesetsY + width / 4);

        points[1][0] = new Point(offsetsX + width / 4, offesetsY + width / 2);
        points[1][1] = new Point(offsetsX + width / 2, offesetsY + width / 2);
        points[1][2] = new Point(offsetsX + (width - width / 4), offesetsY + width / 2);

        points[2][0] = new Point(offsetsX + width / 4, offesetsY + (width - width / 4));
        points[2][1] = new Point(offsetsX + width / 2, offesetsY + (width - width / 4));
        points[2][2] = new Point(offsetsX + (width - width / 4), offesetsY + (width - width / 4));

        /*
        * 5.图片资源的半径
        */
        bitmapR = pointPressed.getHeight() / 2;


        /*
        * 6.设置密码
        * 自然数
        */
        int index = 1;
        for (Point[] points : this.points) {
            for (Point point : points) {
                point.index = index;
                index++;
            }
        }

        /*
        * 7.初始化完成
        */
        isInit = true;

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        isFinished = false;
        movingNoPoint = false;
        movingX = event.getX();
        movingY = event.getY();
        Point point = null;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                //重新绘制
                if(listener!=null)
                {
                    listener.onPatterStart(true);
                }
                resetPoint();
                point = checkSelectPoint();
                if (point != null) {
                    isSelect = true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (isSelect) {
                    point = checkSelectPoint();
                    if (point == null) {
                        movingNoPoint = true;

                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                isFinished = true;
                isSelect = false;
                break;


        }
        //选中重复检查
        if (!isFinished && isSelect && point != null) {
            //交叉点
            if (crossPoint(point)) {
                movingNoPoint = true;
            } else {
                point.state = Point.STATE_PRESSED;

                pointList.add(point);
            }
        }
        //绘制结束
        if (isFinished) {
            //绘制不成立
            if (pointList.size() == 1) {
                resetPoint();
            }

            //绘制错误
            else if (pointList.size() < POINT_SIZE && pointList.size() > 0) {
                errorPoint();
                if (listener != null) {
//                    String pwd="";
//                    //遍历集合
//                    for (int i=0;i<pointList.size();i++) {
//                        pwd=pwd+pointList.get(i).index;
//                    }
                    listener.onPatterChange(null);
                }
            }
            //绘制成功
            else {
                if (listener != null) {
                    String pwd = "";
                    //遍历集合
                    for (int i = 0; i < pointList.size(); i++) {
                        pwd = pwd + pointList.get(i).index;
                    }
                    if(!TextUtils.isEmpty(pwd))
                    {
                        listener.onPatterChange(pwd);
                    }

                }
            }
        }
        //刷新View
        postInvalidate();
        return true;
    }

    //交叉点的检查
    public boolean crossPoint(Point point) {
        if (pointList.contains(point)) {
            return true;
        } else {
            return false;
        }
    }

    //设置绘制不成立
    public void resetPoint() {
        for (int i = 0; i < pointList.size(); i++) {
            Point point = pointList.get(i);
            point.state = Point.STATE_NORMAL;
        }
        pointList.clear();
    }

    //设置绘制错误
    public void errorPoint() {
        for (Point point : pointList) {
            point.state = Point.STATE_ERROR;
        }
    }

    //检查鼠标的x,y
    public Point checkSelectPoint() {
        for (int i = 0; i < points.length; i++) {
            for (int j = 0; j < points[i].length; j++) {
                Point point = points[i][j];
                if (Point.with(point.x, point.y, bitmapR, movingX, movingY)) {
                    return point;
                }
            }
        }
        return null;
    }


    //将点绘制到画布
    private void points2Cavas(Canvas canvas) {
        for (int i = 0; i < points.length; i++) {
            for (int j = 0; j < points[i].length; j++) {
                Point point = points[i][j];
                if (point.state == Point.STATE_PRESSED) {
                    canvas.drawBitmap(pointPressed, point.x - bitmapR, point.y - bitmapR, mpaint);
                } else if (point.state == Point.STATE_ERROR) {
                    canvas.drawBitmap(pointError, point.x - bitmapR, point.y - bitmapR, mpaint);
                } else {
                    canvas.drawBitmap(pointNormal, point.x - bitmapR, point.y - bitmapR, mpaint);
                }
            }
        }
    }

    //自定义的点
    public static class Point {
        //正常
        public static int STATE_NORMAL = 0;
        //选中
        public static int STATE_PRESSED = 1;
        //错误
        public static int STATE_ERROR = 2;
        public float x, y;
        public int index = 0, state = 0;

        public Point() {

        }

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        //距离
        public static double distance(Point a, Point b) {

            //x轴的平方加上y轴的平方,对和开放
            return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x) + Math.abs(a.y - b.y) * Math.abs(a.y - b.y));
        }

        //是否重合
        public static boolean with(float pointX, float pointY, float r, float movingX, float movingY) {
            return Math.sqrt((pointX - movingX) * (pointX - movingX) + (pointY - movingY) * (pointY - movingY)) < r;
        }
    }

    //感知用户绘图的结果---监听器
    public static interface onPatterChangeListener {
        //图案改变
        void onPatterChange(String pwd);

        //图案重新绘制()
        void onPatterStart(boolean isStart);
    }

    //设置图案监听器
    public void setPatterChangeListener(onPatterChangeListener listener) {
        if (listener != null) {
            this.listener = listener;
        }
    }

}
